/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License.You may obtain a copy of the License at
	http://www.mozilla.org/MPL/MPL-1.1.html
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import com.bourre.events.EventType;

import fever.app.accelerator.KeyDefinition;

/**
 * Defines basic data structure for key detection and managment.
 * 
 * <p>Take a look at {@link fever.app.accelerator.KeyboardController} 
 * class for example.
 * 
 * @see fever.app.accelerator.KeyboardController
 * @see fever.app.accelerator.KeyCombo * @see fever.app.accelerator.KeyDefinition
 * 
 * @author Romain Ecarnot
 */
class fever.app.accelerator.Keyboard extends EventType implements KeyDefinition
{
	//-------------------------------------------------------------------------
	// Constants definition
	//-------------------------------------------------------------------------
	
	public static function get DISABLED_DELAY() : Number { return 1000000; }
	
		
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private static var _oKeyMap : Array;
	private static var _oCharMap : Array;
	
	private var _delay : Number;
	private var _name : String;
	
	
	//-------------------------------------------------------------------------
	// Public Properties
	//-------------------------------------------------------------------------
	
	/** Repetition key timer in ms. ( default is 300 ) */
	public static var DEFAULT_DELAY : Number = 300;
	
	/**
	 * Defines repetition timer for instance.
	 *  
	 * <p>To avoid repetition, pass {@link #DISABLED_DELAY}
	 */
	public function get delay() : Number { return _delay; }
	public function set delay( value : Number ) : Void { _setDelay( value ); }
	
	/**
	 * Returns key(s) structure name.
	 * 
	 * @return {@code String}
	 */
	public function get name() : String { return _name; }
	
	
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Returns {@link Keyboard} instance defined by passed-in {@code code}
	 * 
	 * @param code Key (or key sequence id) to search.
	 */
	public static function getStruct( code : Number ) : Keyboard
	{
		return _oKeyMap[code];
	}
	
	/**
	 * Returns {@link Keyboard} instance defined by passed-in {@code char} 
	 * string.
	 */
	public static function getCharStruct( char : String ) : Keyboard
	{
		return _oCharMap[ char ];	
	}
	
	/**
	 * Returns key code from passed-in {@link Keyboard} instance.
	 * 
	 * @param key {@code Keyboard} instance
	 * @return {@code Number} code
	 */
	public static function getCodeFromStruct( key : Keyboard ) : Number
	{
		var l : Number = _oKeyMap.length;
		while(--l > 0) if(_oKeyMap[l] == key) return l;
		return -1;	
	}
	
	/**
	 * Constructor.
	 * 
	 * @param name {@code String} structure's name.
	 */
	public function Keyboard(name : String)
	{
		super( '__accelEvent__' + name );
		
		_name = name;
		_delay = DEFAULT_DELAY;
	}
	
	/**
	 * Returns key definition name.
	 */
	public function getName() : String
	{
		return _name;	
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	/**
	 * Defines repetition delay by passed-in {@code value} number
	 * 
	 * @param value {@code Number} time value in ms.
	 */
	private function _setDelay(value : Number) : Void
	{
		if( value > 0 ) _delay = value;
		else value = Keyboard.DISABLED_DELAY;
	}
	
	
	//-------------------------------------------------------------------------
	// Key constant
	//-------------------------------------------------------------------------
	 
	public static var onKeyA : Keyboard = new Keyboard("a");
	public static var onKeyB : Keyboard = new Keyboard("b");
	public static var onKeyC : Keyboard = new Keyboard("c");
	public static var onKeyD : Keyboard = new Keyboard("d");
	public static var onKeyE : Keyboard = new Keyboard("e");
	public static var onKeyF : Keyboard = new Keyboard("f");
	public static var onKeyG : Keyboard = new Keyboard("g");
	public static var onKeyH : Keyboard = new Keyboard("h");
	public static var onKeyI : Keyboard = new Keyboard("i");
	public static var onKeyJ : Keyboard = new Keyboard("j");
	public static var onKeyK : Keyboard = new Keyboard("k");
	public static var onKeyL : Keyboard = new Keyboard("l");
	public static var onKeyM : Keyboard = new Keyboard("m");
	public static var onKeyN : Keyboard = new Keyboard("n");
	public static var onKeyO : Keyboard = new Keyboard("o");
	public static var onKeyP : Keyboard = new Keyboard("p");
	public static var onKeyQ : Keyboard = new Keyboard("q");
	public static var onKeyR : Keyboard = new Keyboard("r");
	public static var onKeyS : Keyboard = new Keyboard("s");
	public static var onKeyT : Keyboard = new Keyboard("t");
	public static var onKeyU : Keyboard = new Keyboard("u");
	public static var onKeyV : Keyboard = new Keyboard("v");
	public static var onKeyW : Keyboard = new Keyboard("w");
	public static var onKeyX : Keyboard = new Keyboard("x");
	public static var onKeyY : Keyboard = new Keyboard("y");
	public static var onKeyZ : Keyboard = new Keyboard("z");
	
	public static var onKey0 : Keyboard = new Keyboard("0");
	public static var onKey1 : Keyboard = new Keyboard("1");
	public static var onKey2 : Keyboard = new Keyboard("2");
	public static var onKey3 : Keyboard = new Keyboard("3");
	public static var onKey4 : Keyboard = new Keyboard("4");
	public static var onKey5 : Keyboard = new Keyboard("5");
	public static var onKey6 : Keyboard = new Keyboard("6");
	public static var onKey7 : Keyboard = new Keyboard("7");
	public static var onKey8 : Keyboard = new Keyboard("8");
	public static var onKey9 : Keyboard = new Keyboard("9");
	
	public static var onKeyPAD0 : Keyboard = new Keyboard("PAD0");
	public static var onKeyPAD1 : Keyboard = new Keyboard("PAD1");
	public static var onKeyPAD2 : Keyboard = new Keyboard("PAD2");
	public static var onKeyPAD3 : Keyboard = new Keyboard("PAD3");
	public static var onKeyPAD4 : Keyboard = new Keyboard("PAD4");
	public static var onKeyPAD5 : Keyboard = new Keyboard("PAD5");
	public static var onKeyPAD6 : Keyboard = new Keyboard("PAD6");
	public static var onKeyPAD7 : Keyboard = new Keyboard("PAD7");
	public static var onKeyPAD8 : Keyboard = new Keyboard("PAD8");
	public static var onKeyPAD9 : Keyboard = new Keyboard("PAD9");
	
	public static var onKeyMULTIPLY : Keyboard = new Keyboard("Multiply");
	public static var onKeyADD : Keyboard = new Keyboard("Pad +");
	public static var onKeySUBSTRACT : Keyboard = new Keyboard("Pad -");
	public static var onKeyDECIMAL : Keyboard = new Keyboard("Decimal");
	public static var onKeyDIVIDE : Keyboard = new Keyboard("Divide");
	
	public static var onKeyF1 : Keyboard = new Keyboard("F1");
	public static var onKeyF2 : Keyboard = new Keyboard("F2");
	public static var onKeyF3 : Keyboard = new Keyboard("F3");
	public static var onKeyF4 : Keyboard = new Keyboard("F4");
	public static var onKeyF5 : Keyboard = new Keyboard("F5");
	public static var onKeyF6 : Keyboard = new Keyboard("F6");
	public static var onKeyF7 : Keyboard = new Keyboard("F7");
	public static var onKeyF8 : Keyboard = new Keyboard("F8");
	public static var onKeyF9 : Keyboard = new Keyboard("F9");
	public static var onKeyF10 : Keyboard = new Keyboard("F10");
	public static var onKeyF11 : Keyboard = new Keyboard("F11");
	public static var onKeyF12 : Keyboard = new Keyboard("F12");
	public static var onKeyF13 : Keyboard = new Keyboard("F13");
	public static var onKeyF14 : Keyboard = new Keyboard("F14");
	public static var onKeyF15 : Keyboard = new Keyboard("F15");
	
	public static var onKeyBACKSPACE : Keyboard = new Keyboard("Backspace");
	public static var onKeyCAPSLOCK : Keyboard = new Keyboard("Capslock");
	public static var onKeyCONTROL : Keyboard = new Keyboard("Ctrl");
	public static var onKeyDELETEKEY : Keyboard = new Keyboard("Delete");
	public static var onKeyDOWN : Keyboard = new Keyboard("KeyDown");
	public static var onKeyEND : Keyboard = new Keyboard("KeyEnd");
	public static var onKeyENTER : Keyboard = new Keyboard("KeyEnter");
	public static var onKeyESCAPE : Keyboard = new Keyboard("Esc");
	public static var onKeyHOME : Keyboard = new Keyboard("Home");
	public static var onKeyINSERT : Keyboard = new Keyboard("Insert");
	public static var onKeyLEFT : Keyboard = new Keyboard("Left");
	public static var onKeyPGDN : Keyboard = new Keyboard("PageDown");
	public static var onKeyPGUP : Keyboard = new Keyboard("PageUp");
	public static var onKeyRIGHT : Keyboard = new Keyboard("Right");
	public static var onKeySHIFT : Keyboard = new Keyboard("Shift");
	public static var onKeySPACE : Keyboard = new Keyboard("Space");
	public static var onKeyTAB : Keyboard = new Keyboard("Tab");
	public static var onKeyUP : Keyboard = new Keyboard("KeyUp");
	
	
	//Force initialisation only after constant definition.
	private static var __bInitialized : Boolean = __init();
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	private static function __init(Void) : Boolean
	{
		_oKeyMap = new Array();
		
		_oKeyMap[ 65 ] = Keyboard.onKeyA;
		_oKeyMap[ 66 ] = Keyboard.onKeyB;
		_oKeyMap[ 67 ] = Keyboard.onKeyC;
		_oKeyMap[ 68 ] = Keyboard.onKeyD;
		_oKeyMap[ 69 ] = Keyboard.onKeyE;
		_oKeyMap[ 70 ] = Keyboard.onKeyF;
		_oKeyMap[ 71 ] = Keyboard.onKeyG;
		_oKeyMap[ 72 ] = Keyboard.onKeyH;
		_oKeyMap[ 73 ] = Keyboard.onKeyI;
		_oKeyMap[ 74 ] = Keyboard.onKeyJ;
		_oKeyMap[ 75 ] = Keyboard.onKeyK;
		_oKeyMap[ 76 ] = Keyboard.onKeyL;
		_oKeyMap[ 77 ] = Keyboard.onKeyM;
		_oKeyMap[ 78 ] = Keyboard.onKeyN;
		_oKeyMap[ 79 ] = Keyboard.onKeyO;
		_oKeyMap[ 80 ] = Keyboard.onKeyP;
		_oKeyMap[ 81 ] = Keyboard.onKeyQ;
		_oKeyMap[ 82 ] = Keyboard.onKeyR;
		_oKeyMap[ 83 ] = Keyboard.onKeyS;
		_oKeyMap[ 84 ] = Keyboard.onKeyT;
		_oKeyMap[ 85 ] = Keyboard.onKeyU;
		_oKeyMap[ 86 ] = Keyboard.onKeyV;
		_oKeyMap[ 87 ] = Keyboard.onKeyW;
		_oKeyMap[ 88 ] = Keyboard.onKeyX;
		_oKeyMap[ 89 ] = Keyboard.onKeyY;
		_oKeyMap[ 90 ] = Keyboard.onKeyZ;
		_oKeyMap[ 48 ] = Keyboard.onKey0;
		_oKeyMap[ 49 ] = Keyboard.onKey1;
		_oKeyMap[ 50 ] = Keyboard.onKey2;
		_oKeyMap[ 51 ] = Keyboard.onKey3;
		_oKeyMap[ 52 ] = Keyboard.onKey4;
		_oKeyMap[ 53 ] = Keyboard.onKey5;
		_oKeyMap[ 54 ] = Keyboard.onKey6;
		_oKeyMap[ 55 ] = Keyboard.onKey7;
		_oKeyMap[ 56 ] = Keyboard.onKey8;
		_oKeyMap[ 57 ] = Keyboard.onKey9;
		
		_oKeyMap[ 96 ] = Keyboard.onKeyPAD0;
		_oKeyMap[ 97 ] = Keyboard.onKeyPAD1;
		_oKeyMap[ 98 ] = Keyboard.onKeyPAD2;
		_oKeyMap[ 99 ] = Keyboard.onKeyPAD3;
		_oKeyMap[ 100 ] = Keyboard.onKeyPAD4;
		_oKeyMap[ 101 ] = Keyboard.onKeyPAD5;
		_oKeyMap[ 102 ] = Keyboard.onKeyPAD6;
		_oKeyMap[ 103 ] = Keyboard.onKeyPAD7;
		_oKeyMap[ 104 ] = Keyboard.onKeyPAD8;
		_oKeyMap[ 105 ] = Keyboard.onKeyPAD9;
		
		_oKeyMap[ 106 ] = Keyboard.onKeyMULTIPLY;
		_oKeyMap[ 107 ] = Keyboard.onKeyADD;
		_oKeyMap[ 109 ] = Keyboard.onKeySUBSTRACT;
		_oKeyMap[ 110 ] = Keyboard.onKeyDECIMAL;
		_oKeyMap[ 111 ] = Keyboard.onKeyDIVIDE;
		
		_oKeyMap[ 112 ] = Keyboard.onKeyF1;
		_oKeyMap[ 113 ] = Keyboard.onKeyF2;
		_oKeyMap[ 114 ] = Keyboard.onKeyF3;
		_oKeyMap[ 115 ] = Keyboard.onKeyF4;
		_oKeyMap[ 116 ] = Keyboard.onKeyF5;
		_oKeyMap[ 117 ] = Keyboard.onKeyF6;
		_oKeyMap[ 118 ] = Keyboard.onKeyF7;
		_oKeyMap[ 119 ] = Keyboard.onKeyF8;
		_oKeyMap[ 120 ] = Keyboard.onKeyF9;
		_oKeyMap[ 121 ] = Keyboard.onKeyF10;
		_oKeyMap[ 122 ] = Keyboard.onKeyF11;
		_oKeyMap[ 123 ] = Keyboard.onKeyF12;
		_oKeyMap[ 124 ] = Keyboard.onKeyF13;
		_oKeyMap[ 125 ] = Keyboard.onKeyF14;
		_oKeyMap[ 126 ] = Keyboard.onKeyF15;
		
		_oKeyMap[ Key.BACKSPACE ] = Keyboard.onKeyBACKSPACE;
		_oKeyMap[ Key.CAPSLOCK ] = Keyboard.onKeyCAPSLOCK;
		_oKeyMap[ Key.CONTROL ] = Keyboard.onKeyCONTROL;
		_oKeyMap[ Key.DELETEKEY ] = Keyboard.onKeyDELETEKEY;
		_oKeyMap[ Key.DOWN ] = Keyboard.onKeyDOWN;
		_oKeyMap[ Key.END ] = Keyboard.onKeyEND;
		_oKeyMap[ Key.ENTER ] = Keyboard.onKeyENTER;
		_oKeyMap[ Key.ESCAPE ] = Keyboard.onKeyESCAPE;
		_oKeyMap[ Key.HOME ] = Keyboard.onKeyHOME;
		_oKeyMap[ Key.INSERT ] = Keyboard.onKeyINSERT;
		_oKeyMap[ Key.LEFT ] = Keyboard.onKeyLEFT;
		_oKeyMap[ Key.PGDN ] = Keyboard.onKeyPGDN;
		_oKeyMap[ Key.PGUP ] = Keyboard.onKeyPGUP;
		_oKeyMap[ Key.RIGHT ] = Keyboard.onKeyRIGHT;
		_oKeyMap[ Key.SHIFT ] = Keyboard.onKeySHIFT;
		_oKeyMap[ Key.SPACE ] = Keyboard.onKeySPACE;
		_oKeyMap[ Key.TAB ] = Keyboard.onKeyTAB;
		_oKeyMap[ Key.UP ] = Keyboard.onKeyUP;
		
		
		_oCharMap = new Array();
		_oCharMap[ 'a' ] = Keyboard.onKeyA;
		_oCharMap[ 'b' ] = Keyboard.onKeyB;
		_oCharMap[ 'c' ] = Keyboard.onKeyC;
		_oCharMap[ 'd' ] = Keyboard.onKeyD;
		_oCharMap[ 'e' ] = Keyboard.onKeyE;
		_oCharMap[ 'f' ] = Keyboard.onKeyF;
		_oCharMap[ 'g' ] = Keyboard.onKeyG;
		_oCharMap[ 'h' ] = Keyboard.onKeyH;
		_oCharMap[ 'i' ] = Keyboard.onKeyI;
		_oCharMap[ 'j' ] = Keyboard.onKeyJ;
		_oCharMap[ 'k' ] = Keyboard.onKeyK;
		_oCharMap[ 'l' ] = Keyboard.onKeyL;
		_oCharMap[ 'm' ] = Keyboard.onKeyM;
		_oCharMap[ 'n' ] = Keyboard.onKeyN;
		_oCharMap[ 'o' ] = Keyboard.onKeyO;
		_oCharMap[ 'p' ] = Keyboard.onKeyP;
		_oCharMap[ 'q' ] = Keyboard.onKeyQ;
		_oCharMap[ 'r' ] = Keyboard.onKeyR;
		_oCharMap[ 's' ] = Keyboard.onKeyS;
		_oCharMap[ 't' ] = Keyboard.onKeyT;
		_oCharMap[ 'u' ] = Keyboard.onKeyU;
		_oCharMap[ 'v' ] = Keyboard.onKeyV;
		_oCharMap[ 'w' ] = Keyboard.onKeyW;
		_oCharMap[ 'x' ] = Keyboard.onKeyX;
		_oCharMap[ 'y' ] = Keyboard.onKeyY;
		_oCharMap[ 'z' ] = Keyboard.onKeyZ;
		_oCharMap[ '0' ] = Keyboard.onKey0;
		_oCharMap[ '1' ] = Keyboard.onKey1;
		_oCharMap[ '2' ] = Keyboard.onKey2;
		_oCharMap[ '3' ] = Keyboard.onKey3;
		_oCharMap[ '4' ] = Keyboard.onKey4;
		_oCharMap[ '5' ] = Keyboard.onKey5;
		_oCharMap[ '6' ] = Keyboard.onKey6;
		_oCharMap[ '7' ] = Keyboard.onKey7;
		_oCharMap[ '8' ] = Keyboard.onKey8;
		_oCharMap[ '9' ] = Keyboard.onKey9;
		
		return true;
	}		
}